package com.yxx.community.service;

import com.yxx.community.dto.CommentDTO;
import com.yxx.community.enums.CommentTypeEnum;
import com.yxx.community.enums.NotificationEnum;
import com.yxx.community.enums.NotificationStatusEnum;
import com.yxx.community.exception.CustomizeErrorCode;
import com.yxx.community.exception.CustomizeException;
import com.yxx.community.mapper.*;
import com.yxx.community.model.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author: YuXinXin
 * @Description:
 * @Date:Created in 20:40 2020/2/6
 **/
@Service
public class CommentService {
  @Autowired
  private CommentMapper commentMapper;
  @Autowired
  private CommentExtMapper commentExtMapper;

  @Autowired
  private QuestionMapper questionMapper;

  @Autowired
  private QuestionExtMapper questionExtMapper;

  @Autowired
  private UserMapper userMapper;

  @Autowired
  private NotificationMapper notificationMapper;

  @Transactional//为方法体全部加上事务
  public void insert(Comment comment, User commentator) {
    if(comment.getParentId()==null || comment.getParentId()==0){
      throw new CustomizeException(CustomizeErrorCode.TARGET_TYPE_NOT_FIND);
    }
    if(comment.getType()==null || !CommentTypeEnum.isExit(comment.getType())){
      throw new CustomizeException(CustomizeErrorCode.TARGET_TYPE_WRONG);
    }
    if(comment.getType()==CommentTypeEnum.COMMENT.getType()){ //回复评论
      Comment dbComment = commentMapper.selectByPrimaryKey(comment.getParentId());
      if (dbComment==null){
        throw new CustomizeException(CustomizeErrorCode.COMMENT_NOT_FIND);
      }
      commentMapper.insert(comment);
      //增加回复数
      Question question = questionMapper.selectByPrimaryKey(dbComment.getParentId());
      if (question==null){
        throw new CustomizeException(CustomizeErrorCode.COMMENT_NOT_FIND);
      }
      question.setCommentCount(1);
      questionExtMapper.inCommentCount(question);
      //增加评论的回复数
      comment.setSubComment(1);
      commentExtMapper.inSubComment(comment);
      //创建通知
      createNotification(comment, dbComment.getCommentator(), commentator.getName(), question.getTitle(), NotificationEnum.REPLY_COMMENT, comment.getParentId());
    }else {//回复问题
      commentMapper.insert(comment);
      //增加回复数
      Question question = questionMapper.selectByPrimaryKey(comment.getParentId());
      if (question==null){
        throw new CustomizeException(CustomizeErrorCode.QUESTION_NOT_FIND);
      }
      question.setCommentCount(1);
      questionExtMapper.inCommentCount(question);
      //创建通知
      createNotification(comment, question.getCreator(), commentator.getName(),question.getTitle(),NotificationEnum.REPLY_QUESTION, question.getId());
    }

  }

  private void createNotification(Comment comment, Long receiver, String notifierName, String outerTitle, NotificationEnum type, Long outerId) {
    Notification notification = new Notification();
    notification.setGmtCreate(System.currentTimeMillis());
    notification.setType(type.getType());
    notification.setOuterId(outerId);
    notification.setNotifier(comment.getCommentator());
    notification.setStatus(NotificationStatusEnum.UREAD.getStatus());
    notification.setReceiver(receiver);
    notification.setReceiver(receiver);
    notification.setNotifierName(notifierName);
    notification.setOuterTitle(outerTitle);
    notificationMapper.insert(notification);
  }

  public List<CommentDTO> listByTargetId(long id, CommentTypeEnum type) {
    CommentExample commentExample = new CommentExample();
    commentExample.setOrderByClause("gmt_create desc");
    commentExample.createCriteria()
            .andParentIdEqualTo(id)
            .andTypeEqualTo(type.getType());
    List<Comment> comments = commentMapper.selectByExample(commentExample);
    if(comments.size()==0){
      return new ArrayList<>();
    }
    //获取去重的评论人
    Set<Long> commentators = comments.stream().map(comment -> comment.getCommentator()).collect(Collectors.toSet());
    List<Long> userIds=new ArrayList<>();
    userIds.addAll(commentators);


    //获取评论人并转化为map
    UserExample userExample = new UserExample();
    userExample.createCriteria().andIdIn(userIds);
    List<User> users = userMapper.selectByExample(userExample);
    Map<Long, User> userMap = users.stream().collect(Collectors.toMap(user -> user.getId(), user -> user));

    //转换comment为commentDTO
    List<CommentDTO> commentDTOS = comments.stream().map(comment -> {
      CommentDTO commentDTO = new CommentDTO();
      BeanUtils.copyProperties(comment,commentDTO);
      commentDTO.setUser(userMap.get(comment.getCommentator()));
      return commentDTO;
    }).collect(Collectors.toList());
    return commentDTOS;
  }
}
